﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using PmSoft.Core.FileStorage.Configuration;
using PmSoft.Core.FileStorage.Providers;

namespace PmSoft.Core.FileStorage;

/// <summary>
/// 存储相关依赖注入扩展方法
/// </summary>
public static class StorageServiceCollectionExtensions
{
	/// <summary>
	/// 添加存储服务到依赖注入容器
	/// </summary>
	/// <param name="services">服务集合</param>
	/// <param name="configuration">配置对象</param>
	/// <returns>服务集合</returns>
	public static IServiceCollection AddStorageServices(this IServiceCollection services, IConfiguration configuration)
	{
		// 绑定 Storage 配置到 StorageSettings 类
		services.Configure<StorageSettings>(configuration.GetSection("Storage"));

		// 注册 IFileStorageProvider，根据配置动态选择实现
		services.TryAddSingleton<IFileStorageProvider>(sp =>
		{
			// 从 DI 容器中获取 StorageSettings 配置
			var options = sp.GetRequiredService<IOptions<StorageSettings>>();
			var storageSettings = options.Value;

			// 检查 storageSettings 是否为 null
			if (storageSettings == null)
			{
				throw new InvalidOperationException("Storage 配置未在 appsettings.json 中定义。");
			}

			// 检查 Provider 是否为空或无效
			if (string.IsNullOrWhiteSpace(storageSettings.Provider))
			{
				throw new InvalidOperationException("Storage.Provider 未指定有效的存储提供商。");
			}

			// 根据 Provider 值选择存储提供商
			switch (storageSettings.Provider.ToLower())
			{
				case "minio":
					if (storageSettings.MinIO == null)
						throw new InvalidOperationException("MinIO 配置未提供。");
					ValidateMinioSettings(storageSettings.MinIO); // 验证 MinIO 配置
					return new MinioStorageProvider(
						storageSettings.MinIO.Endpoint,
						storageSettings.MinIO.AccessKey,
						storageSettings.MinIO.SecretKey);
				case "s3":
					if (storageSettings.S3 == null)
						throw new InvalidOperationException("S3 配置未提供。");
					ValidateS3Settings(storageSettings.S3); // 验证 AWS S3 配置
					return new S3StorageProvider(
						storageSettings.S3.AccessKey,
						storageSettings.S3.SecretKey,
						storageSettings.S3.Region);
				case "localfilesystem":
					//if (storageSettings.LocalFileSystem == null)
					//	throw new InvalidOperationException("LocalFileSystem 配置未提供。");
					//ValidateLocalFileSystemSettings(storageSettings.LocalFileSystem); // 验证本地文件系统配置
					return new LocalFileSystemStorageProvider(
						storageSettings.LocalFileSystem.RootPath);

				default:
					throw new InvalidOperationException($"不支持的存储提供商: {storageSettings.Provider}");
			}
		});

		return services;
	}

	/// <summary>
	/// 验证 MinIO 配置的有效性
	/// </summary>
	/// <param name="settings">MinIO 配置对象</param>
	private static void ValidateMinioSettings(MinioSettings settings)
	{
		if (string.IsNullOrWhiteSpace(settings.Endpoint))
			throw new InvalidOperationException("MinIO.Endpoint 未指定。");
		if (string.IsNullOrWhiteSpace(settings.AccessKey))
			throw new InvalidOperationException("MinIO.AccessKey 未指定。");
		if (string.IsNullOrWhiteSpace(settings.SecretKey))
			throw new InvalidOperationException("MinIO.SecretKey 未指定。");
	}

	/// <summary>
	/// 验证 S3 配置的有效性
	/// </summary>
	/// <param name="settings">S3 配置对象</param>
	private static void ValidateS3Settings(S3Settings settings)
	{
		if (string.IsNullOrWhiteSpace(settings.AccessKey))
			throw new InvalidOperationException("S3.AccessKey 未指定。");
		if (string.IsNullOrWhiteSpace(settings.SecretKey))
			throw new InvalidOperationException("S3.SecretKey 未指定。");
		if (string.IsNullOrWhiteSpace(settings.Region))
			throw new InvalidOperationException("S3.Region 未指定。");
	}

	/// <summary>
	/// 验证本地文件系统配置的有效性
	/// </summary>
	/// <param name="settings">本地文件系统配置对象</param>
	//private static void ValidateLocalFileSystemSettings(LocalFileSystemSettings settings)
	//{
	//	if (string.IsNullOrWhiteSpace(settings.RootPath))
	//		throw new InvalidOperationException("LocalFileSystem.RootPath 未指定。");
	//}
}